﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CsvHelper;
using System.IO;
using System.Configuration;


namespace RoardersAgentSim.CSVUtils
{
    /// <summary>
    /// CSV initializer procedure
    /// </summary>
    public class Initializer
    {
        private string mapDirectoryPath;
        private string zoneFilePath;
        private string nodeFilePath;
        private string linkFilePath;
        private string populationFilePath;

        public Initializer(string mapDirectoryPath)
        {
            this.mapDirectoryPath = mapDirectoryPath;
            if (!mapDirectoryPath.EndsWith(@"\"))
                mapDirectoryPath += @"\";
            zoneFilePath = mapDirectoryPath + "zone.csv";
            nodeFilePath = mapDirectoryPath + "node.csv";
            linkFilePath = mapDirectoryPath + "link.csv";
            populationFilePath = mapDirectoryPath + "population.csv";
        }

        #region parsers
        /// <summary>
        /// Parse the zone file
        /// </summary>
        internal List<CSVMapping.ZoneMapping> ParseZones()
        {
            if (string.IsNullOrWhiteSpace(zoneFilePath))
                throw new Exception("Invalid zone file path." + "Cannot find file: " + zoneFilePath);
            try
            {
                List<CSVMapping.ZoneMapping> zones = null;
                using (var fileReader = File.OpenText(zoneFilePath))
                {
                    var csv = new CsvHelper.CsvReader(fileReader);
                    SetupCSVReaderConfiguration(csv);
                    zones = csv.GetRecords<CSVMapping.ZoneMapping>().ToList();
                }
                return zones;
            }
            catch (Exception ex)
            {
                LogHelper.LogError("Please check the columns and data from the csv file: " + zoneFilePath);
                throw ex;
            }
        }

        /// <summary>
        /// Parse the node file
        /// </summary>
        internal List<CSVMapping.NodeMapping> ParseNodes()
        {
            if (string.IsNullOrWhiteSpace(nodeFilePath))
                throw new Exception("Invalid node file path." + "Cannot find file: " + nodeFilePath);
            try
            {
                List<CSVMapping.NodeMapping> nodes = null;
                using (var fileReader = File.OpenText(nodeFilePath))
                {
                    var csv = new CsvHelper.CsvReader(fileReader);
                    SetupCSVReaderConfiguration(csv);
                    nodes = csv.GetRecords<CSVMapping.NodeMapping>().ToList();
                }
                return nodes;
            }
            catch (Exception ex)
            {
                LogHelper.LogError("Please check the columns and data from the csv file: " + nodeFilePath);
                throw ex;
            }

        }

        /// <summary>
        /// Parse the links file
        /// </summary>
        internal List<CSVMapping.LinkMapping> ParseLinks()
        {
            if (string.IsNullOrWhiteSpace(linkFilePath))
                throw new Exception("Invalid link file path." + "Cannot find file: " + linkFilePath);
            try
            {
                List<CSVMapping.LinkMapping> links = null;
                using (var fileReader = File.OpenText(linkFilePath))
                {
                    var csv = new CsvHelper.CsvReader(fileReader);
                    SetupCSVReaderConfiguration(csv);
                    links = csv.GetRecords<CSVMapping.LinkMapping>().ToList();
                }
                return links;
            }
            catch (Exception ex)
            {
                LogHelper.LogError("Please check the columns and data from the csv file: " + linkFilePath);
                throw ex;
            }
        }

        /// <summary>
        /// Parse the population file
        /// </summary>
        internal List<CSVMapping.PopulationMapping> ParsePopulation()
        {
            if (string.IsNullOrWhiteSpace(populationFilePath))
                throw new Exception("Invalid link file path." + "Cannot find file: " + linkFilePath);
            try
            {
                List<CSVMapping.PopulationMapping> population = null;
                using (var fileReader = File.OpenText(populationFilePath))
                {
                    var csv = new CsvHelper.CsvReader(fileReader);
                    SetupCSVReaderConfiguration(csv);
                    population = csv.GetRecords<CSVMapping.PopulationMapping>().ToList();
                }
                return population;
            }
            catch (Exception ex)
            {
                LogHelper.LogError("Please check the columns and data from the csv file: " + linkFilePath);
                throw ex;
            }
        }

        #endregion
        #region initialise the csv reader configuration
        /// <summary>
        /// Initialise the csv reader configuration
        /// </summary>
        /// <param name="csv"></param>
        private void SetupCSVReaderConfiguration(CsvReader csv)
        {
            csv.Configuration.AllowComments = true;
            csv.Configuration.Comment = ConfigurationManager.AppSettings["CSV_COMMENT"][0];
            csv.Configuration.Delimiter = ConfigurationManager.AppSettings["CSV_DELIMITER"];
            csv.Configuration.HasHeaderRecord = true;
            csv.Configuration.IgnoreHeaderWhiteSpace = true;
            csv.Configuration.IsHeaderCaseSensitive = false;
        }
        #endregion
    }
}
